package cn.topcodes.tcsf.app.service.impl;

import cn.topcode.unicorn.utils.JsonUtil;
import cn.topcode.unicorn.utils.StringUtil;
import cn.topcodes.tcsf.app.domain.push.PushProtocol;
import cn.topcodes.tcsf.app.service.PushService;
import org.ddpush.im.v1.client.appserver.Pusher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
 * Created by Unicorn on 2017/7/26.
 */
@Service("pushService")
public class PushServiceImpl implements PushService {

    private static Logger logger = LoggerFactory.getLogger(PushServiceImpl.class);

    private Pusher pusher;

    @Autowired
    private AppUserServiceImpl appUserService;

    @Value("${ddpush.host}")
    private String ddpushHost;

    @Value("${ddpush.port}")
    private int ddpushPort;

    private int ddpushTimeout = 1000;

    /**
     * 通过账号推送消息
     * @param cmd   推送类型
     * @param content   推送内容
     */
    @Override
    public void pushByAccount(String account, String cmd, Object content) {
        List<String> tokens = appUserService.findTokensByUsername(account);
        if(tokens.isEmpty()) {
            return;
        }
        for(String token : tokens) {
            pushByToken(token, cmd, content);
        }
    }

    /**
     * 通过token推送消息
     * @param token 用户登录凭证
     * @param cmd   推送类型
     * @param content   推送内容
     */
    @Override
    public void pushByToken(String token, String cmd, Object content) {
        PushProtocol pushProtocol = new PushProtocol();
        pushProtocol.setCmd(cmd);
        pushProtocol.setBody(JsonUtil.toJson(content));
        String json = JsonUtil.toJson(pushProtocol);
        this.pushByToken(token, json);
    }

    /**
     * 根据token推送文本
     *
     * @param token 用户登录凭证
     * @param text  文本
     */
    @Override
    public void pushByToken(String token, String text) {
        this.pushByToken(token, text.getBytes(Charset.forName("UTF-8")));
    }

    /**
     * 根据token推送二进制数据
     *
     * @param token 用户登录凭证
     * @param data  文本
     */
    @Override
    public void pushByToken(String token, byte[] data) {
        if(StringUtil.isBlank(token)) {
            logger.warn("推送token不能为空,token: " + token);
            return;
        }
        if(pusher == null) {
            try {
                pusher = new Pusher(ddpushHost,ddpushPort, ddpushTimeout);
            } catch (Exception e) {
                pusher = null;
                logger.warn("DDPUSH推送服务器连接失败:" + e.getMessage());
            }
        }
        if(pusher != null) {
            try {
                pusher.push0x20Message(md5(token), data);
            } catch (Exception e) {
                logger.warn("DDPUSH消息推送失败", e);
                closeConn();
            }
        }
    }

    @PreDestroy
    public void destory() {
        closeConn();
    }

    private void closeConn() {
        if(pusher != null) {
            try {
                pusher.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            pusher = null;
        }
    }

    private byte[] md5(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(text.getBytes("UTF-8"));
        return md.digest();
    }
}
